home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / utils / xad / developer / sources / clients / packdev.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  9KB  |  315 lines

  1. #ifndef XADMASTER_PACKDEV_C
  2. #define XADMASTER_PACKDEV_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        PackDev.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: PackDev.c 1.1 (13.02.1999)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    PackDev disk archiver client
  12.  
  13.  1.0   13.06.98 : first version
  14.  1.1   13.02.99 : started again with that client
  15. */
  16.  
  17. /* For now SectorLabel information is ignored, as current
  18. xadmaster.library does not support SectorLabels. */
  19.  
  20. #include <proto/xadmaster.h>
  21. #include <proto/exec.h>
  22. #include <devices/trackdisk.h>
  23. #include "SDI_compiler.h"
  24. #define SDI_TO_ANSI
  25. #include "SDI_ASM_STD_protos.h"
  26. #include "xpkstuff.c"
  27.  
  28. #ifndef XADMASTERFILE
  29. #define PackDev_Client        FirstClient
  30. #define NEXTCLIENT        0
  31. UBYTE version[] = "$VER: PackDev 1.1 (13.02.1999)";
  32. #endif
  33. #define PACKDEV_VERSION        1
  34. #define PACKDEV_REVISION    1
  35.  
  36. struct PackDevHead {
  37.   UBYTE        pd_Header[4];    /* equals 'PKD\x13' */
  38.   ULONG        pd_BlockNum;    /* Number of blocks */
  39.   ULONG        pd_BlockSize;    /* size of one block */
  40.   ULONG        pd_Reserved;    /* Reserved blocks */
  41.   ULONG        pd_TrackLength;    /* Length of one track*/
  42.   ULONG        pd_xpkBufferSize; /* in byte */
  43.   ULONG        pd_xpkPacker;    /* XPK packer type */
  44.   ULONG pad1;    /* These are fields containing the XPK packer name */
  45.   ULONG pad2;    /* Don't know, why the author used 24bytes instead */
  46.   ULONG pad3;    /* of the required 4. */
  47.   ULONG pad4;    /* The fields are ignored by that client */
  48.   ULONG pad5;
  49.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  50.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  51. };
  52.  
  53. struct PackDevHeadOld {
  54.   UBYTE        pd_Header[4];    /* equals 'PKD\x11' */
  55.   ULONG        pd_BlockNum;    /* Number of blocks */
  56.   ULONG        pd_BlockSize;    /* size of one block */
  57.   ULONG        pd_Reserved;    /* Reserved blocks */
  58.   ULONG        pd_TrackLength;    /* Length of one track*/
  59.   ULONG        pd_xpkBufferSize; /* in byte */
  60.   ULONG        pd_xpkPacker;    /* XPK packer type */
  61.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  62.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  63. };
  64.  
  65. /* Every block has following structure:
  66.  ULONG size
  67.  ULONG data[...]
  68.  ULONG checksum
  69.  
  70. Where data are the blocks and additionally the SectorLabels (16 Byte).
  71. NOTE: xadmaster does not support to extract the label data in current version!
  72.  
  73. Checksum is missing in PackDev11 Version.
  74. */
  75.  
  76. #define PKD_XPKPACKED    (1<<0)
  77. #define PKD_OLDMODE    (1<<1)
  78.  
  79. ASM(BOOL) PackDev_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  80. REG(a6, struct xadMasterBase *xadMasterBase))
  81. {
  82.   if(((ULONG *)data)[0] == 0x504B4413 || ((ULONG *)data)[0] == 0x504B4411)
  83.     return 1;
  84.   else
  85.     return 0;
  86. }
  87.  
  88. LONG PKDdecrBuf(STRPTR *buf, ULONG *i, struct xadArchiveInfo *ai,
  89. struct xadMasterBase *xadMasterBase, ULONG oldmode)
  90. {
  91.   LONG err, size;
  92.   if(!(err = xadHookAccess(XADAC_READ, 4, &size, ai)))
  93.   {
  94.     if(!(err = xpkDecrunch(buf, i, ai, xadMasterBase)))
  95.     {
  96.       if(!oldmode)
  97.         err = xadHookAccess(XADAC_READ, 4, &size, ai);
  98.     }
  99.   }
  100.   return err;
  101. }
  102.  
  103. /* maybe there are some errors in that code, not tested yet */
  104. ASM(LONG) PackDev_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  105. REG(a6, struct xadMasterBase *xadMasterBase))
  106. {
  107.   struct PackDevHead h;
  108.   LONG err;
  109.   struct ExecBase * SysBase = xadMasterBase->xmb_SysBase;
  110.  
  111.   if(!(err = xadHookAccess(XADAC_READ, sizeof(struct PackDevHeadOld), &h, ai)))
  112.   {
  113.     if(h.pd_Header[3] == 0x11 || !(err = xadHookAccess(XADAC_READ,
  114.     sizeof(struct PackDevHead)-sizeof(struct PackDevHeadOld), ((STRPTR) &h) +
  115.     sizeof(struct PackDevHeadOld), ai)))
  116.     {
  117.       struct xadDiskInfo *xdi;
  118.       ULONG blksiz = 0, i, j, dat[10];
  119.       STRPTR buf = 0;
  120.  
  121.       if(h.pd_Header[3] == 0x11)
  122.       {
  123.         h.pd_KnownFileSys = ((struct PackDevHeadOld *) &h)->pd_KnownFileSys;
  124. /*      h.pd_xpkMode = ((struct PackDevHeadOld *) &h)->pd_xpkMode; */
  125.       }
  126.     
  127.       /* check for password flag */
  128.       if(h.pd_xpkPacker && !err && !(err = xadHookAccess(XADAC_READ, 40, dat, ai))
  129.       && !(err = xadHookAccess(XADAC_INPUTSEEK, -40, 0, ai)))
  130.       {
  131.         if(dat[9] & (1<<25))
  132.           ai->xai_Flags |= XADAIF_CRYPTED;
  133.       }
  134.  
  135.       if(h.pd_KnownFileSys)
  136.       {
  137.         blksiz = h.pd_BlockNum;
  138.         if(h.pd_xpkPacker)
  139.         {
  140.           j = ai->xai_InPos;
  141.           if(!(err = PKDdecrBuf(&buf, &i, ai, xadMasterBase, h.pd_Header[3] == 0x11)))
  142.             err = xadHookAccess(XADAC_INPUTSEEK, j-ai->xai_InPos, 0, ai);
  143.         }
  144.         else
  145.         {
  146.           if(!(buf = (STRPTR) AllocVec((i = blksiz>>3), MEMF_ANY)))
  147.             err = XADERR_NOMEMORY;
  148.           else
  149.             err = xadHookAccess(XADAC_READ, i, buf, ai);
  150.         }
  151.       }
  152.     
  153.       if(!err)
  154.       {
  155.         if((xdi = (struct xadDiskInfo *) xadAllocObject(XADOBJ_DISKINFO,
  156.         blksiz ? XAD_OBJBLOCKENTRIES : TAG_DONE, blksiz, TAG_DONE)))
  157.         {
  158.           if(ai->xai_Flags & XADAIF_CRYPTED)
  159.             xdi->xdi_Flags |= XADDIF_CRYPTED;
  160.           xdi->xdi_Flags |= XADDIF_NOCYLINDERS|XADDIF_NOLOWCYL|
  161.                         XADDIF_NOHIGHCYL|XADDIF_NOHEADS|XADDIF_NOCYLSECTORS;
  162.           xdi->xdi_TotalSectors = h.pd_BlockNum;
  163.           xdi->xdi_SectorSize = h.pd_BlockSize;
  164.           xdi->xdi_TrackSectors = h.pd_TrackLength / h.pd_BlockSize;
  165.           xdi->xdi_EntryNumber = 1;
  166.           i = 0;
  167.           if(h.pd_xpkPacker)
  168.             i |= PKD_XPKPACKED;
  169.           if(h.pd_Header[3] == 0x11)
  170.             i |= PKD_OLDMODE;
  171.           xdi->xdi_PrivateInfo = (APTR) i;
  172.           ai->xai_DiskInfo = xdi;
  173.  
  174.       /* does nothing if blksiz == 0 */
  175.       for(i = 0; i < blksiz; ++i)
  176.           {
  177.             if(i < h.pd_Reserved || (buf[i/8] & ((1 << (7-(i%8))))))
  178.               xdi->xdi_BlockInfo[i] |= XADBIF_CLEARED;
  179.           }
  180.         }
  181.         else
  182.           err = XADERR_NOMEMORY;
  183.       }
  184.       if(buf)
  185.         FreeVec(buf);
  186.     }
  187.   }
  188.  
  189.   return err;
  190. }
  191.  
  192. ASM(LONG) PackDev_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  193. REG(a6, struct xadMasterBase *xadMasterBase))
  194. {
  195.   ULONG p, i, j, trsec, numsecs = 0;
  196.   LONG err = 0, secsize;
  197.   struct xadDiskInfo *di;
  198.   STRPTR temp;
  199.   struct ExecBase *SysBase = xadMasterBase->xmb_SysBase;
  200.   
  201.   p = ai->xai_InPos;
  202.   di = ai->xai_CurDisk;
  203.   secsize = di->xdi_SectorSize;
  204.   trsec = di->xdi_TrackSectors;
  205.  
  206.   if(!(temp = AllocVec(di->xdi_SectorSize*di->xdi_TrackSectors, MEMF_ANY)))
  207.     return XADERR_NOMEMORY;
  208.  
  209.   if(!(((ULONG) di->xdi_PrivateInfo) & PKD_XPKPACKED))
  210.   {
  211.     numsecs = 0;
  212.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  213.     {
  214.       j = (i % trsec)*secsize;
  215.     
  216.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  217.         memset(temp+j, 0, secsize);
  218.       else
  219.       {
  220.         err = xadHookAccess(XADAC_READ, secsize, temp+j, ai);
  221.         ++numsecs;
  222.       }
  223.       /* skip the sectorlabel and write data */
  224.       if((i % trsec) == (trsec-1) && !err)
  225.       {
  226.         if(!numsecs || !(err = xadHookAccess(XADAC_INPUTSEEK, TD_LABELSIZE*numsecs, 0, ai)))
  227.           err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  228.         numsecs = 0;
  229.       }
  230.     }
  231.   }
  232.   else
  233.   {
  234.     ULONG size;
  235.     LONG pos = 0, ressize;
  236.     STRPTR buf = 0;
  237.  
  238.     err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  239.     (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE));
  240.  
  241.     if(di->xdi_BlockInfo)
  242.       pos += di->xdi_TotalSectors>>3;
  243.  
  244.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  245.     {
  246.       j = (i % trsec)*secsize;
  247.       
  248.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  249.         memset(temp+j, 0, secsize);
  250.       else
  251.       {
  252.         ++numsecs;
  253.         if((ressize = size-pos) >= secsize)
  254.         {
  255.           CopyMem(buf+pos, temp+j, secsize);
  256.           pos += secsize;
  257.         }
  258.         else
  259.         {
  260.           if(ressize > 0)
  261.           {
  262.             CopyMem(buf+pos, temp+j, ressize);
  263.             pos += ressize;
  264.           }
  265.           else if(ressize < 0)
  266.             ressize = 0;
  267.           FreeVec(buf);
  268.           buf = 0;
  269.           pos -= size;
  270.           if(!(err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  271.           (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE))))
  272.           {
  273.             CopyMem(buf+pos, temp+j+ressize, secsize-ressize);
  274.             pos += secsize-ressize;
  275.           }
  276.         }
  277.       }
  278.       /* skip the sectorlabel and write data */
  279.       if((i % trsec) == (trsec-1) && !err)
  280.       {
  281.         pos += TD_LABELSIZE*numsecs;
  282.         err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  283.         numsecs = 0;
  284.       }
  285.     }
  286.     if(buf)
  287.       FreeVec(buf);
  288.   }
  289.  
  290.   if(p != ai->xai_InPos)
  291.     xadHookAccess(XADAC_INPUTSEEK, p-ai->xai_InPos, 0, ai);
  292.  
  293.   FreeVec(temp);
  294.  
  295.   return err;
  296. }
  297.  
  298. ASM(void) PackDev_Free(REG(a0, struct xadArchiveInfo *ai),
  299. REG(a6, struct xadMasterBase *xadMasterBase))
  300. {
  301.   if(ai->xai_DiskInfo)
  302.   {
  303.     xadFreeObjectA(ai->xai_DiskInfo, 0);
  304.     ai->xai_DiskInfo = 0; /* clear the entry */
  305.   }
  306. }
  307.  
  308. struct xadClient PackDev_Client = {
  309. NEXTCLIENT, XADCLIENT_VERSION, 1, PACKDEV_VERSION, PACKDEV_REVISION,
  310. 4, XADCF_DISKARCHIVER, XADCID_PACKDEV, "PackDev",
  311. (BOOL (*)()) PackDev_RecogData, (LONG (*)()) PackDev_GetInfo,
  312. (LONG (*)()) PackDev_UnArchive, (void (*)()) PackDev_Free};
  313.  
  314. #endif /* XADASTER_PACKDEV_C */
  315.